/**
 * @file    must_can.c
 * @brief   逆变器协议-美世乐-CAN通信接口V6.0
 * @author  Liuwei
 * @version 1.0.1
 * @date    2023-11-15
 * 
 * @copyright Copyright (c) 2023 JBD-Energy Storage Technology Co. LTD
 * 
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version   <th>Author   <th>Description
 * <tr><td>2023-11-15 <td>1.0.1     <td>Liuwei   <td>首次创建
 * </table>
 */

/* includes ------------------------------------------------------------------*/
#include "must_can.h"
#include "If_can.h"
#include "var_mng.h"
#include "param_mng.h"
#include "cfg_prj.h"
#include "diagnosis.h"
#include "parallel.h"
/* macro/define --------------------------------------------------------------*/

/* typedef -------------------------------------------------------------------*/
typedef struct 
{
    uint32_t can_id;      /* !< 报文ID */
    uint16_t send_cycle; /* !< 发送周期 */
    uint16_t send_cnt;   /* !< 计时器 */
    void(*pfunc_get_frame_msg)(can_frame_type *);
}send_frame_type;

/* local functions -----------------------------------------------------------*/
static void can_get_0x00030100_msg(can_frame_type *can_msg);
static void can_get_0x00030200_msg(can_frame_type *can_msg);
static void can_get_0x00030400_msg(can_frame_type *can_msg);
static void can_get_0x00030500_msg(can_frame_type *can_msg);
static void can_get_0x00030700_msg(can_frame_type *can_msg);
static uint16_t must_get_err_msg(void);
/* static variables ----------------------------------------------------------*/
static send_frame_type send_frame_list[] = 
{
    {0x00030100 , 1000 , 0 ,can_get_0x00030100_msg },
    {0x00030200 , 1000 , 0 ,can_get_0x00030200_msg },
    {0x00030400 , 1000 , 0 ,can_get_0x00030400_msg },
    {0x00030500 , 1000 , 0 ,can_get_0x00030500_msg },
    {0x00030700 , 1000 , 0 ,can_get_0x00030700_msg },
};

#define CAN_LIST_NUM     (sizeof(send_frame_list)/sizeof(send_frame_type))
/* global variables ----------------------------------------------------------*/

/** ------------------------------------------------------------------------- *
  *                             Global function
 ** ------------------------------------------------------------------------- */
/**
 * @brief  获取需要发送的数据信息
 * @param  cycle
 * @param  can_buf
 * @return uint8_t 
 */
uint8_t must_can_get_msg(uint32_t cycle , can_frame_type *can_buf)
{
    uint8_t i = 0;
    uint8_t msg_num = 0;

    for( i = 0; i < CAN_LIST_NUM; ++ i)
    {
        send_frame_list[i].send_cnt += cycle;
        if(send_frame_list[i].send_cnt >= send_frame_list[i].send_cycle)
        {
            send_frame_list[i].send_cnt = 0;
            send_frame_list[i].pfunc_get_frame_msg(&can_buf[msg_num ++]); 
        }
    }

    return msg_num;
}

/** ------------------------------------------------------------------------- *
  *                              Local function
 ** ------------------------------------------------------------------------- */
static void can_get_0x00030100_msg(can_frame_type *can_msg)
{
    can_msg->frame_type = CAN_FRAME_DATA;
    can_msg->id_type = CAN_ID_EXT;
    can_msg->dlc = 8;
    can_msg->id = 0x00030100;

    can_msg->data.half_buf[0] = var_get_data(VAR_ID_TP_SOP_CV);
    can_msg->data.half_buf[1] = var_get_data(VAR_ID_TP_SOP_CC);
    can_msg->data.half_buf[2] = var_get_data(VAR_ID_TP_SOP_DV);
    can_msg->data.half_buf[3] = var_get_data(VAR_ID_TP_SOP_DC);
}

static void can_get_0x00030200_msg(can_frame_type *can_msg)
{
    can_msg->frame_type = CAN_FRAME_DATA;
    can_msg->id_type = CAN_ID_EXT;
    can_msg->dlc = 8;
    can_msg->id = 0x00030200;
	
    can_msg->data.half_buf[0] = 0;
    can_msg->data.half_buf[1] = 0;
	if(parallel_get_pcs_ctrl(PARALLEL_PCS_CHG_EN) == FALSE)
    	can_msg->data.half_buf[2] = 1;
	else
		can_msg->data.half_buf[2] = 0;
	if(parallel_get_pcs_ctrl(PARALLEL_PCS_DSG_EN) == FALSE)
   	    can_msg->data.half_buf[3] = 1;
	else
		can_msg->data.half_buf[3] = 0;
}

static void can_get_0x00030400_msg(can_frame_type *can_msg)
{
	/* 告警及保护信息 */
	int32_t temp = 0;
	
    can_msg->frame_type = CAN_FRAME_DATA;
    can_msg->id_type = CAN_ID_EXT;
    can_msg->dlc = 8;
    can_msg->id = 0x00030400;

    can_msg->data.half_buf[0] = var_get_data(VAR_ID_TP_VOLT) * 0.1;
    temp = (var_get_data(VAR_ID_TP_CURR_H) << 16) + var_get_data(VAR_ID_TP_CURR_L);
    can_msg->data.half_buf[1] = temp*0.1; //
    can_msg->data.half_buf[2] = var_get_data(VAR_ID_TP_AVG_TEMP) * 0.1 - 273.1;
    can_msg->data.half_buf[3] = must_get_err_msg();
}

static void can_get_0x00030500_msg(can_frame_type *can_msg)
{
	uint8_t soh = 0;
    can_msg->frame_type = CAN_FRAME_DATA;
    can_msg->id_type = CAN_ID_EXT;
    can_msg->dlc = 8;
    can_msg->id = 0x00030500;
	soh = var_get_data(VAR_ID_TP_SOH);
	if(soh > 100)
		soh = 100;
    can_msg->data.half_buf[0] = var_get_data(VAR_ID_TP_SOC);
    can_msg->data.half_buf[1] = soh;
    can_msg->data.half_buf[2] = var_get_data(VAR_ID_TP_SOC) * 100;
    can_msg->data.half_buf[3] = 0;
}

static void can_get_0x00030700_msg(can_frame_type *can_msg)
{
    can_msg->frame_type = CAN_FRAME_DATA;
    can_msg->id_type = CAN_ID_EXT;
    can_msg->dlc = 8;
    can_msg->id = 0x00030700;

    if(parallel_get_pcs_ctrl(PARALLEL_PCS_FROCE_CHG1) == TRUE)
        can_msg->data.half_buf[0] = 1;
    else
        can_msg->data.half_buf[0] = 0;
    can_msg->data.half_buf[1] = 0;
    can_msg->data.half_buf[2] = 0;
    can_msg->data.half_buf[3] = 0;
}

static uint16_t must_get_err_msg(void)
{
    uint16_t alarm_msg = 0;

    if(master_data_reg.total_prp_msg.bit.cov || master_data_reg.total_prp_msg.bit.bov)
        alarm_msg |= (0 << 1);
    if(master_data_reg.total_prp_msg.bit.cuv || master_data_reg.total_prp_msg.bit.buv)
        alarm_msg |= (1 << 1);
    if(master_data_reg.total_prp_msg.bit.occ)
        alarm_msg |= (2 << 1);
    if(master_data_reg.total_prp_msg.bit.ocd)
        alarm_msg |= (3 << 1);
    if(master_data_reg.total_prp_msg.bit.otc || master_data_reg.total_prp_msg.bit.otd)
        alarm_msg |= (4 << 1);    
    if(master_data_reg.total_prp_msg.bit.utc || master_data_reg.total_prp_msg.bit.utd)
        alarm_msg |= (5 << 1);
    if(master_data_reg.total_prp_msg.bit.sc)
        alarm_msg |= (6 << 1);
    if(master_data_reg.total_prp_msg.bit.otm || master_data_reg.total_prp_msg.bit.ote)
        alarm_msg |= (7 << 1);    

    return alarm_msg;
}
/********** Copyright (c) 2023 JBD-Energy Storage Technology Co. LTD *********/


